#include "Drv_W5500.h"
#include <string.h>
#include <stdio.h>
#include "iwdg.h"
#include "socket.h"
//#include "wizchip_conf.h"
//#include "spi.h"
//#include "w5500.h"

uint16_t Local_Port = 6000;
#define W5500_CMD_TIMEOUT 1 // 500ms 超时
#define MAX_CONNECT_TRY 10  // 最多尝试5次
uint8_t synSentRetry[5] = {0};  // 每个Socket一个重试计数器
uint8_t index = 0;
volatile uint32_t system_millis = 0;  // 系统ms时间
//static uint32_t last_heartbeat_time = 0;  //心态时间
uint32_t last_heartbeat_time[5] = {0};
//#define NETWORK_CHECK_INTERVAL  5000  // 每隔5秒检测一次网络状态

W5500_TypeDef gst_W5500_Dev =
{
    .pst_hspi     = &hspi2,
    .pst_CS_GPIO  = GPIOB,
    .ul_CS_PIN    = GPIO_PIN_12,
    .pst_RST_GPIO = GPIOC,
    .ul_RST_PIN   = GPIO_PIN_7,
    
    .uch_PHYConnect     = 0,                                     /*网线默认未连接*/
    .st_CfgMsg.auch_SHA = {0x00, 0x08, 0xDC, 0x11, 0x11, 0x11},  /*源MAC地址*/
    .st_CfgMsg.auch_GA  = {192, 168, 58, 1},                      /*网关IP*/
    .st_CfgMsg.auch_SUB = {255, 255, 255, 0},                    /*子网掩码*/
    .st_CfgMsg.auch_SIP = {192, 168, 58, 10},                     /*源IP地址*/
    .st_CfgMsg.uin_RTR  = 2000,                                  /*重试超时时间*/
    .st_CfgMsg.uch_RCR  = 8,                                     /*重试次数*/

    /*Socket端口号配置*/
    .st_Socket[0].uin_Port = 5000,
    .st_Socket[1].uin_Port = 5001,
    .st_Socket[2].uin_Port = 5002,
    .st_Socket[3].uin_Port = 5003,
    .st_Socket[4].uin_Port = 5004,
    .st_Socket[5].uin_Port = 5005,
    //.st_Socket[6].uin_Port = 5006,
    //.st_Socket[7].uin_Port = 5007,


    /*Socket缓存配置，默认2k*/
    .st_Socket[0].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[0].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    .st_Socket[1].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[1].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    .st_Socket[2].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[2].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    .st_Socket[3].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[3].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    .st_Socket[4].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[4].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    .st_Socket[5].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    .st_Socket[5].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    // .st_Socket[6].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    // .st_Socket[6].uch_TxBuffSize = W5500_Sn_TXBUF_2KB,
    // .st_Socket[7].uch_RxBuffSize = W5500_Sn_RXBUF_2KB,
    // .st_Socket[7].uch_TxBuffSize = W5500_Sn_TXBUF_2KB
};



static void Drv_W5500_Delay(uint16_t Delay);

/**
 * 函数功能：W5500初始化
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_Init(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_Reset(pst_EthStruct);
    Drv_W5500_PHYCheck(pst_EthStruct);           /*检查网线连接*/

    Drv_W5500_SetSHAR(pst_EthStruct);            /*设置MAC地址*/
    Drv_W5500_SetGAR(pst_EthStruct);             /*设置网关*/
    Drv_W5500_SetSUBR(pst_EthStruct);            /*设置子网掩码*/
    Drv_W5500_SetSIPR(pst_EthStruct);            /*设置源IP地址*/

    Drv_W5500_SetRTR(pst_EthStruct);             /*设置重试超时时间*/
    Drv_W5500_SetRCR(pst_EthStruct);             /*设置重试次数*/
	
	// 打印结构体的每个字段
   //printf("IP Address: %s\n", pst_EthStruct->st_CfgMsg.auch_SIP); 
   printf("IP Address: %d.%d.%d.%d\n", 
       pst_EthStruct->st_CfgMsg.auch_SIP[0],
       pst_EthStruct->st_CfgMsg.auch_SIP[1],
       pst_EthStruct->st_CfgMsg.auch_SIP[2],
       pst_EthStruct->st_CfgMsg.auch_SIP[3]);	
   printf("Gateway: %s\n", pst_EthStruct->st_CfgMsg.auch_GA);
   printf("Subnet Mask: %s\n", pst_EthStruct->st_CfgMsg.auch_SUB);

	
	
    /*注册SPI回调函数*/
    //reg_wizchip_spi_cbfunc(w5500_read_byte, w5500_write_byte);   


}


static void __w5500_spi_read_buffer(uint8_t *buff, uint16_t len) {
	HAL_SPI_Receive(&hspi2, buff, len, HAL_MAX_DELAY);
}

static void __w5500_spi_write_buffer(uint8_t *buff, uint16_t len) {
	HAL_SPI_Transmit(&hspi2, buff, len, HAL_MAX_DELAY);
}

uint8_t w5500_read_byte(void) {
	uint8_t byte;
	__w5500_spi_read_buffer(&byte, sizeof(byte));
	return byte;
}

void w5500_write_byte(uint8_t byte) {
	__w5500_spi_write_buffer(&byte, sizeof(byte));
}


/**
 * 函数功能：W5500复位
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_Reset(W5500_TypeDef *pst_EthStruct)
{
    /*复位芯片*/
    HAL_GPIO_WritePin(pst_EthStruct->pst_RST_GPIO, pst_EthStruct->ul_RST_PIN, GPIO_PIN_RESET);
    HAL_Delay(5);
    HAL_IWDG_Refresh(&hiwdg);  // 喂狗
    HAL_GPIO_WritePin(pst_EthStruct->pst_RST_GPIO, pst_EthStruct->ul_RST_PIN, GPIO_PIN_SET);
    //HAL_Delay(100);
    for (int i = 0; i < 10; i++)  // 拆分100ms，分批喂狗
    {
        HAL_Delay(10);
        HAL_IWDG_Refresh(&hiwdg);  // 喂狗
    }
}

/**
 * 函数功能：TCP服务端
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 */
void Drv_TCPServer(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    if((IS_W5500_SOCKET_REG(uch_Socket)) == false)
    {
        return;
    }

    uint8_t Socket_State;
    uint8_t uch_SnIR;
    uint8_t uch_SocketIndex;
    uint16_t uin_Len;

    /*获取Socket的状态*/
    Socket_State = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
		//printf("Socket %d Status: 0x%02X\n", uch_Socket, Socket_State);
    switch (Socket_State)
    {

    /*Socket关闭状态下，配置Socket*/
    case W5500_Sn_SR_CLOSED:

        /*配置Socket*/
        Drv_W5500_SocketCfg(pst_EthStruct, uch_Socket, W5500_Sn_MR_TCP, W5500_Sn_MR_NDACK);
        break;

    /*Socket已经初始化状态*/
    case W5500_Sn_SR_INIT:
        //printf("Socket %d is in INIT state, trying to connect...\n", uch_Socket);
        /*Socket切换到监听状态*/
        Drv_W5500_Listen(pst_EthStruct, uch_Socket); 
        break;

    /*Socket已经处于监听模式*/
    case W5500_Sn_SR_LISTEN:
        break;

    /*Socket建立连接状态*/
    case W5500_Sn_SR_ESTABLISHED:
        uch_SocketIndex = uch_Socket >> 2;
        uch_SnIR = Drv_W5500_GetSn_IR(pst_EthStruct, uch_Socket);

        /*读取Socket中断寄存器*/
        if ((uch_SnIR & W5500_Sn_IR_CON) != 0)  
        {
            /*当Socket的连接成功中断（CON标志置1）后，清除中断标志，防止重复触发中断*/
            Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_CON);

            /*设置Socket保活时间，TCP协议下有效*/
            Drv_W5500_SetSn_KPALVTR(pst_EthStruct, uch_Socket, 1);
        }
				/*建立连接后开启接收中断 -新增-*/
				Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket,W5500_Sn_CR_RECV);
				

        /*读取Sn_RX_RSR寄存器，获取接收缓存中已经接收和保存数据大小*/
        uin_Len = Drv_W5500_GetSn_RX_RSR(pst_EthStruct, uch_Socket);  

        /*接收字节大小*/
        *pst_EthStruct->st_Socket[uch_SocketIndex].puin_RxSize = uin_Len;  

        /*Socket缓存接收到数据, 从缓存读取数据*/
        if (uin_Len > 0)
        {
            Drv_W5500_TCPRecv(pst_EthStruct, uch_Socket);
        }

        /*Socket缓存没有接收到数据，利用心跳监测连接状态*/
        else
        {
            Drv_W5500_KeepAlive(pst_EthStruct, uch_Socket);
        }
        break;
    
    /*Socket等待关闭状态*/
    case W5500_Sn_SR_CLOSE_WAIT:
        Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
        break;

    case W5500_Sn_SR_UDP:
    case W5500_Sn_SR_MACRAW:
    case W5500_Sn_SR_SYNSENT:
    case W5500_Sn_SR_SYNRECV:
    case W5500_Sn_SR_FIN_WAIT:
    case W5500_Sn_SR_COLSING:
    case W5500_Sn_SR_TIME_WAIT:
    case W5500_Sn_SR_LAST_ACK:
        break;

    default:
        break;
    }
}

/**
 * 函数功能：TCP客户端
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 */
void Drv_TCPClient(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, const uint8_t *puch_ServerIP, uint16_t uin_ServerPort)
{
    if((IS_W5500_SOCKET_REG(uch_Socket)) == false)
    {
        return;
    }

    uint8_t Socket_State;
    uint8_t uch_SnIR;
    uint8_t uch_SocketIndex;
    uint16_t uin_Len;
    // if(uch_Socket == 0x15)
    // {      
    //   //uint16_t uin_Port = Drv_W5500_GetSn_Port(pst_EthStruct, uch_Socket);
    //   //Drv_W5500_SetSn_Port (pst_EthStruct, uch_Socket, 5005);
    //   // 获取当前的端口号
    //   uint16_t uin_Port1 = Drv_W5500_GetSn_Port(pst_EthStruct, 0x09);
    //   uint16_t uin_Port2 = Drv_W5500_GetSn_Port(pst_EthStruct, 0x15);      
    //   // 打印端口号
    //   //printf("Socket %d Source Port is : %d\n", 0x09, uin_Port1);
    //   //printf("Socket %d Source Port is : %d\n", 0x15, uin_Port2);
  
    // }
    

    /* 获取Socket的状态 */
    Socket_State = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
//		Socket_State = Drv_W5500_MyGetSn_SR(uch_Socket);
//    if (uch_Socket==0x15)
//    {
//        /* code */
//        printf("Socket %d Status: 0x%02X\n", (uch_Socket>>2), Socket_State);
//    }
    
	  //printf("Socket %d Status: 0x%02X\n", uch_Socket, Socket_State);

    switch (Socket_State)
    {
    /*Socket关闭状态下，配置Socket*/
    case W5500_Sn_SR_CLOSED:
        /*配置Socket*/
		    //printf("Socket %d Status: 0x%02X\n", uch_Socket>>2, Socket_State);
        Drv_W5500_SocketCfg(pst_EthStruct, uch_Socket, W5500_Sn_MR_TCP, W5500_Sn_MR_NDACK);
		    Drv_W5500_Delay(5);
        break;

	  /* INIT 状态下，直接尝试连接 */
    case W5500_Sn_SR_INIT:
        //printf("Socket %d is in INIT state, trying to connect...\n", (uch_Socket >> 2));
        if (Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort) == SOCK_OK)
        {
            printf("Socket %d is in INIT state, connect success\n", (uch_Socket >> 2));
        }
        else
        {
            Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
            // printf("Socket %d is in INIT state, can`t connect success\n", (uch_Socket >> 2));
        }
        break;
    /* Socket正在连接 */
    case W5500_Sn_SR_SYNSENT:
			  
		    index=uch_Socket >>2;
				synSentRetry[index]++;
    
        if (synSentRetry[index] > 20)  // 超过重试阈值，认为连接失败
        {
            printf("Socket %d SYNSENT 超时，重试次数: %d，强制关闭并重连\n", index,synSentRetry[index]);
            synSentRetry[index] = 0;
		    
            Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
            //HAL_Delay(200); // 等待一下再重连
            //Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort);
        }
		    
//			printf("Socket %d is in SYNSENT(Connectting) state,\n", (uch_Socket >> 2));
//		
//      break;
		/* Socket已经监听，如果由SERVER端连接回来，则需要断开连接重新建立SOCKTET */
    case W5500_Sn_SR_LISTEN:
        //printf("Socket %d is in LISTEN state, trying to CloseSocket...\n", uch_Socket);
        //        //Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort);
        //        break;
        printf("Socket %d is in LISTEN state (Client Mode Error) code is %d, closing and reconnecting...\n", (uch_Socket >> 2),Socket_State);

        // 关闭异常的Socket
        Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
        // HAL_Delay(500); // 等待硬件释放资源

        // 重新初始化Socket
        if (Drv_W5500_SocketCfg(pst_EthStruct, uch_Socket, W5500_Sn_MR_TCP, W5500_Sn_MR_NDACK) != true)
        {
            printf("Socket %d re-initialization failed.\n", uch_Socket);
            break;
        }

        // 尝试重新连接
        if (Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort))
        {
            printf("Socket %d reconnected successfully.\n", uch_Socket);
        }
        else
        {
            printf("Socket %d reconnection failed.\n", uch_Socket);
        }
        break;

    /* Socket已连接，准备发送或接收数据 */
    case W5500_Sn_SR_ESTABLISHED:
			
//		    if (uch_Socket==0x15)
//        {
//            /* code */
//            printf("Socket %d Status: 0x%02X\n", (uch_Socket>>2), Drv_W5500_MyGetSn_SR(uch_Socket));
//        }
			  //printf("Socket %d Have ESTABLISHED.\n", uch_Socket>>2);
        uch_SocketIndex = uch_Socket >> 2;
        uch_SnIR = Drv_W5500_GetSn_IR(pst_EthStruct, uch_Socket);

        /* 读取Socket中断寄存器 */
        if ((uch_SnIR & W5500_Sn_IR_SENDOF) != 0)  
        {
            /* 清除中断标志位 */
            Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_SENDOF);
        }

        if ((uch_SnIR & W5500_Sn_IR_TIMEOUT) != 0)  
        {
            /* 清除中断标志位 */
            Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_TIMEOUT);
            
            /* 处理超时，可选择重连或其他操作 */
            Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
            Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort);
					  break;
        }
				
				/* 3. 检查服务器是否主动断开连接（DISCON） */
//        if ((uch_SnIR & W5500_Sn_IR_DISCON) != 0)
//        {
//					  printf("Socket %d SR ESTABLISHED But server Discon.\n", uch_Socket>>2);
//            Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_DISCON);
//		    
//            printf("Socket %d server disconnected, reconnecting...\n", uch_Socket >> 2);
//		    
//            Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);  
//            //Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort);
//            break;
//        }
				
				// 不实际发数据，但调用 send 函数检测 Socket 是否正常
//        int ret = Drv_W5500_TCPSend(pst_EthStruct, uch_Socket);
//        if (ret <= 0)
//        {
//            Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
//            //Drv_W5500_Connect(pst_EthStruct, uch_Socket, ip, port);
//        }

        /* 读取Sn_RX_RSR寄存器，获取接收缓存中已经接收和保存数据大小 */
        uin_Len = Drv_W5500_GetSn_RX_RSR(pst_EthStruct, uch_Socket);  

        /* 接收字节大小 */
        *pst_EthStruct->st_Socket[uch_SocketIndex].puin_RxSize = uin_Len;  

        /* Socket缓存接收到数据, 从缓存读取数据 */
//        while (uin_Len > 0)
//        {
//            Drv_W5500_TCPRecv(pst_EthStruct, uch_Socket);
//            printf("Socket %d received %d bytes.\n", (uch_Socket>>2), uin_Len);
//            //延时接收 防止丢数据
//            //主要防止短时间内小包过多导致接收缓冲被覆盖
//            HAL_Delay(50);
//            //再次读取剩余数据
//            uin_Len = Drv_W5500_GetSn_RX_RSR(pst_EthStruct, uch_Socket);
//        }
          while (uin_Len > 0)
          {
              Drv_W5500_TCPRecv(pst_EthStruct, uch_Socket);
              printf("Socket %d received %d bytes.\n", (uch_Socket >> 2), uin_Len);
        
              HAL_Delay(50);  // 延时接收，防止丢包
        
              uin_Len = Drv_W5500_GetSn_RX_RSR(pst_EthStruct, uch_Socket);
          }

        
        break;

    /* Socket等待关闭状态 */
    case W5500_Sn_SR_CLOSE_WAIT:
        Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
        break;

    /* 其他状态暂不做处理 */
//    case W5500_Sn_SR_UDP:
//    case W5500_Sn_SR_MACRAW:
//    case W5500_Sn_SR_FIN_WAIT:
//    case W5500_Sn_SR_TIME_WAIT:
//    case W5500_Sn_SR_LAST_ACK:
//    case W5500_Sn_SR_SYNRECV:
    //case W5500_Sn_SR_FIN_WAIT2:
    case W5500_Sn_SR_COLSING:
        break;

    default:
			  printf("Unhandled socket state: %d\n", uch_Socket>>2);
        break;
    }
}


#define TCP_CLIENT_SOCK 0
#define TCP_DEMO_BUFFER_SIZE 2048
uint8_t __tcp_demo_buffer[TCP_DEMO_BUFFER_SIZE];



#define TCP_LOCAL_PORT 6000



/**
 * 函数功能：监听Socket
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 */
void Drv_W5500_Listen(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t SR_Data;
    
    SR_Data = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);

    if(SR_Data == W5500_Sn_SR_INIT)
    {
        Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_LISTEN);
        while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket));
    }
}

/**
 * 函数功能：关闭Socke
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
void Drv_W5500_CloseSocket(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    /*清除中断标志位*/
    Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, 0xFF);

    /*关闭Socket*/
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_CLOSE);
    
    /*等待Socket关闭*/
    while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);  
}

/**
 * 函数功能：W5500物理层检测
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_PHYCheck(W5500_TypeDef *pst_EthStruct)
{
	//static uint32_t lastCheckTime = 0;
    uint8_t uch_ReceiveData;
    //读取PHYCONFIG寄存器
    Drv_W5500_GetPHY(pst_EthStruct, &uch_ReceiveData);

	printf("PHY Connect is %d\n",pst_EthStruct->uch_PHYConnect);  
    //判断网络连接状态
    if((uch_ReceiveData & W5500_PHYCFGR_LNK) != 0)
    {
			if (!pst_EthStruct->uch_PHYConnect)
      {
          printf("Network connection reply！\r\n");
          pst_EthStruct->uch_PHYConnect = 1;
      }
      //pst_EthStruct->uch_PHYConnect = 1;
      //return;
    }         
    //网线未连接
    else
    {
			if (pst_EthStruct->uch_PHYConnect)
      {
				 printf("Network disconnected! Attempting to reconnect...\r\n");
         pst_EthStruct->uch_PHYConnect = 0;
         //HAL_Delay(100);
		  }         				
    }
}

/**
 * 函数功能：发起TCP连接
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 *           puch_ServerIP 目标服务器IP地址
 *           uin_ServerPort 目标端口
 * 返 回 值：无
 */
uint8_t Drv_W5500_Connect(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, const uint8_t *puch_ServerIP, uint16_t uin_ServerPort)
{
    //设置源端口SourcePort
    //Drv_W5500_SetSn_SPORT(pst_EthStruct, uch_Socket, TCP_LOCAL_PORT);
    // 设置目标服务器IP
    Drv_W5500_SetSn_DIPR(pst_EthStruct, uch_Socket, puch_ServerIP);

    // 设置目标服务器端口
    Drv_W5500_SetSn_DPORT(pst_EthStruct, uch_Socket, uin_ServerPort);

    uint8_t SR_Data = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
    if (SR_Data != W5500_Sn_SR_INIT)
    {
        //printf("Socket %d is not in INIT state. Status: 0x%02X\n", (uch_Socket>>2), SR_Data);
        return 0; // 失败
    }

    // 发送连接命令
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_CONNECT);

    // 等待连接命令完成
    while (Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket));

    // 检查连接状态,这里如果时间太长没有及时喂狗就重启了 
    uint32_t timeout = 20; // 超时时间，单位 ms
    while (timeout--)
    {
        SR_Data = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
        if (SR_Data == W5500_Sn_SR_ESTABLISHED)
        {
            printf("Socket %d connected successfully.\n", (uch_Socket>>2));
            return 1; // 成功
        }
        else if (SR_Data == W5500_Sn_SR_CLOSED)
        {
            //printf("Socket %d failed to connect. Status: CLOSED\n", (uch_Socket>>2));
            return 0; // 失败
        }
        HAL_Delay(1); // 延时 1ms，避免占用 CPU
    }

    //printf("Socket %d connection timeout. Status: 0x%02X\n", (uch_Socket>>2), SR_Data);
    return 0; // 失败
}


/**
 * 函数功能：TCP接收数据
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 *           Len 接收数据长度
 * 返 回 值：无
 */
void Drv_W5500_TCPRecv(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint16_t uin_RX_RD;
    uint16_t uin_RX_WR;
    uint16_t uin_DataLen;
    uint8_t uch_SocketIndex;

    /*读取保存在接收缓存中数据的首地址*/
    uin_RX_RD = Drv_W5500_GetSn_Rx_RD(pst_EthStruct, uch_Socket);

    /*读取Sn_RX_WR寄存器值*/
    uin_RX_WR = Drv_W5500_GetSn_Rx_WR(pst_EthStruct, uch_Socket);

    if(uin_RX_WR >= uin_RX_RD)
    {
        uin_DataLen = uin_RX_WR - uin_RX_RD;
    }
    else
    {
        uin_DataLen = (0xFFFF - uin_RX_RD) + uin_RX_WR + 1;
    }

    /*从接收缓存中读取数据*/
    uch_SocketIndex = uch_Socket >> 2;

    /*更新Socket接收字节数*/
    *pst_EthStruct->st_Socket[uch_SocketIndex].puin_RxSize = uin_DataLen;

    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_RX_BUFF(uin_RX_RD, uch_Socket), pst_EthStruct->st_Socket[uch_SocketIndex].puch_RxBuff, uin_DataLen);

    /*更新接收缓存起始地址*/
    uin_RX_RD += uin_DataLen;
    Drv_W5500_SetSn_Rx_RD(pst_EthStruct, uch_Socket, uin_RX_RD);

    /*Socket设置为接收状态*/
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_RECV);
    while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);

    /*接收数据标志位置位*/
    pst_EthStruct->st_Socket[uch_SocketIndex].uch_HaveRecvFlag = 1;
}

/**
 * 函数功能：TCP发送数据
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 * 返 回 值：true 成功，false 失败
 */
uint8_t Drv_W5500_TCPSend(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    if((IS_W5500_SOCKET_REG(uch_Socket)) == false)
    {
        return false;
    }

    uint8_t Socket_State;
    uint8_t uch_SocketIndex;
    uint16_t uin_Addr;
    uint16_t uin_DataLen;

    /*获取Socket的状态*/
    Socket_State = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
		//printf("Drv_W5500_TCPSend %d state is 0x%02X\n ",uch_Socket>>2,Socket_State);
		
    /*TCP没有连接，返回错误*/
    if ((Socket_State != W5500_Sn_SR_ESTABLISHED) && (Socket_State != W5500_Sn_SR_CLOSE_WAIT))
    {
				if (uch_Socket==0x15)
        {
            /* code */
            printf("Socket %d Status: 0x%02X\n", (uch_Socket>>2), Drv_W5500_MyGetSn_SR(uch_Socket));
        }
        return false;
    }

    /*读取发送缓存的首地址*/
    uin_Addr = Drv_W5500_GetSn_TX_WR(pst_EthStruct, uch_Socket);
    
    /*向发送缓存写入数据*/
    uch_SocketIndex = uch_Socket >> 2;
    uin_DataLen = *pst_EthStruct->st_Socket[uch_SocketIndex].puin_TxSize;
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_TX_BUFF(uin_Addr, uch_Socket), pst_EthStruct->st_Socket[uch_SocketIndex].puch_TxBuff, uin_DataLen);

    /*更新发送缓存的首地址*/
    uin_Addr += uin_DataLen;
    Drv_W5500_SetSn_TX_WR(pst_EthStruct, uch_Socket, uin_Addr);        		
		
    /*Socket设置为发送状态*/
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_SEND);
    while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);

    return true;
}

/**
 * 函数功能：TCP发送数据（扩展版，支持自定义数据）
 * 参    数：
 *   pst_EthStruct W5500结构体指针
 *   uch_Socket    Socket编号
 *   pData         要发送的数据指针
 *   len           要发送的数据长度
 * 返 回 值：发送成功字节数，失败返回 <= 0
 */
uint8_t Drv_W5500_TCPSendEx(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t *pData, uint16_t len)
{
    if ((IS_W5500_SOCKET_REG(uch_Socket)) == false || pData == NULL || len == 0)
    {
        return -1;
    }

    uint8_t Socket_State = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);

    if ((Socket_State != W5500_Sn_SR_ESTABLISHED) && (Socket_State != W5500_Sn_SR_CLOSE_WAIT))
    {
        return -2;
    }

    uint16_t uin_Addr = Drv_W5500_GetSn_TX_WR(pst_EthStruct, uch_Socket);

    // 写入数据到TX缓冲区
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_TX_BUFF(uin_Addr, uch_Socket), pData, len);

    // 更新发送缓冲区偏移
    uin_Addr += len;
    Drv_W5500_SetSn_TX_WR(pst_EthStruct, uch_Socket, uin_Addr);

    // 发起发送命令
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_SEND);
    while (Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);

    return len;
}
/**
 * 函数功能：TCP发送数据（伪发送）
 * 参    数：
 *   pst_EthStruct W5500结构体指针
 *   uch_Socket    Socket编号
 * 返 回 值：发送成功字节数，失败返回 false
 */
uint8_t Drv_W5500_SendDummy(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t state = Drv_W5500_GetSn_SR(pst_EthStruct, uch_Socket);
    if (state != W5500_Sn_SR_ESTABLISHED && state != W5500_Sn_SR_CLOSE_WAIT)
    {
        return false;
    }

    uint8_t uch_SnIR = Drv_W5500_GetSn_IR(pst_EthStruct, uch_Socket);

    // 清除 TIMEOUT 标志（避免历史数据干扰）
    if (uch_SnIR & W5500_Sn_IR_TIMEOUT)
    {
        Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_TIMEOUT);
    }

    // 发起空包（伪发送）
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_SEND);
    while (Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);

    // 读取中断标志，判断是否触发超时（说明断线）
    uch_SnIR = Drv_W5500_GetSn_IR(pst_EthStruct, uch_Socket);
    if (uch_SnIR & W5500_Sn_IR_TIMEOUT)
    {
        // 清除 TIMEOUT 标志
        Drv_W5500_SetSn_IR(pst_EthStruct, uch_Socket, W5500_Sn_IR_TIMEOUT);
        return false;  // 表示发送失败，连接断开
    }

    return true; // 正常
}

/**
 * 函数功能：清除Socket有接收数据标志位
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 * 返 回 值：无
 */
void Drv_W5500_ClearRecvFlag(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_SocketIndex;

    uch_SocketIndex = uch_Socket >> 2;
    pst_EthStruct->st_Socket[uch_SocketIndex].uch_HaveRecvFlag = 0;
}

/**
 * 函数功能：获取Socket有接收数据标志位
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 * 返 回 值：true 标志位置位，false 标志位没有置位
 */
uint8_t Drv_W5500_GetRecvFlag(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_SocketIndex;

    uch_SocketIndex = uch_Socket >> 2;

    if(pst_EthStruct->st_Socket[uch_SocketIndex].uch_HaveRecvFlag != 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
 * 函数功能：设置Socket通信协议和端口号
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 *           Protocol 通信协议
 *           Flag 延时应答标志
 * 返 回 值：true 成功，false 失败
 */
uint8_t Drv_W5500_SocketCfg(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t Protocol, uint8_t Flag)
{
    if(((IS_W5500_SOCKET_REG(uch_Socket)) == false) || (IS_W5500_MR_PROTOCOL(Protocol) == false))
    {
        return false;
    }
    
    uint8_t uch_SocketIndex;

    /*关闭Socket*/
    Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);

    /*设置Socket协议类型，延时应答*/
    Drv_W5500_SetSn_MR(pst_EthStruct, uch_Socket, Flag | Protocol);
    
    /*设置Socket端口号*/
    uch_SocketIndex = uch_Socket >> 2;

    if(pst_EthStruct->st_Socket[uch_SocketIndex].uin_Port != 0)
    {
        //printf("Socket %d port is %d 0\r\n", uch_Socket>>2, pst_EthStruct->st_Socket[uch_SocketIndex].uin_Port);
        Drv_W5500_SetSn_Port(pst_EthStruct, uch_Socket, pst_EthStruct->st_Socket[uch_SocketIndex].uin_Port);
    }
    else
    {
        Drv_W5500_SetSn_Port(pst_EthStruct, uch_Socket, Local_Port);
       
        /*更新W5500结构体端口号成员变量*/
        pst_EthStruct->st_Socket[uch_SocketIndex].uin_Port = Local_Port;
        Local_Port++;
    }

    /*设置收发缓存*/
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_RXBUF_SIZE(uch_Socket), pst_EthStruct->st_Socket[uch_SocketIndex].uch_RxBuffSize);
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_TXBUF_SIZE(uch_Socket), pst_EthStruct->st_Socket[uch_SocketIndex].uch_TxBuffSize);
    
    /*开启Socket*/
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_OPEN);
		
	uint32_t startTime = HAL_GetTick(); // 获取当前时间
    //while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);
	while (Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0) 
    {
        if ((HAL_GetTick() - startTime) > W5500_CMD_TIMEOUT) 
        {
            printf("Socket %d Command Timeout!\n", uch_Socket);
            return false; // 超时后退出
        }    
    }
    
 

    /*设置TCP Keep-Alive 超时时间（单位：5秒），如5表示25秒*/
    Drv_W5500_SetSn_KPALVTR(pst_EthStruct, uch_Socket, 1);
    return true;
}

/**
 * 函数功能：Socket发送心跳包
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
void Drv_W5500_KeepAlive(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    /*向发送缓存写入数据*/
    Drv_W5500_SetSn_CR(pst_EthStruct, uch_Socket, W5500_Sn_CR_SEND_KEEP);

    while(Drv_W5500_GetSn_CR(pst_EthStruct, uch_Socket) != 0);
}

/**
 * 函数功能：设置MAC地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetSHAR(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_SHAR0_OFFSET), pst_EthStruct->st_CfgMsg.auch_SHA, 6);
}

/**
 * 函数功能：设置网关IP地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetGAR(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_GAR0_OFFSET), pst_EthStruct->st_CfgMsg.auch_GA, 4);
}

/**
 * 函数功能：设置子网掩码寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetSUBR(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_SUBR0_OFFSET), pst_EthStruct->st_CfgMsg.auch_SUB, 4);
}

/**
 * 函数功能：设置源IP地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetSIPR(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_SIPR0_OFFSET), pst_EthStruct->st_CfgMsg.auch_SIP, 4);
}

/**
 * 函数功能：设置RTR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetRTR(W5500_TypeDef *pst_EthStruct)
{
    uint8_t TxData[2];

    TxData[0] = (pst_EthStruct->st_CfgMsg.uin_RTR & 0xFF00) >> 8;
    TxData[1] = pst_EthStruct->st_CfgMsg.uin_RTR & 0x00FF;

    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_RTR0_OFFSET), TxData, 2);
}

/**
 * 函数功能：设置RCR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_SetRCR(W5500_TypeDef *pst_EthStruct)
{
    Drv_W5500_WriteMem(pst_EthStruct, W5500_MR(W5500_RCR_OFFSET), &pst_EthStruct->st_CfgMsg.uch_RCR, 1);
}

/**
 * 函数功能：获取MAC地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_GetSHAR(W5500_TypeDef *pst_EthStruct, uint8_t *pData)
{
    Drv_W5500_ReadMem(pst_EthStruct, W5500_MR(W5500_SHAR0_OFFSET), pData, 4);
    
}

/**
 * 函数功能：获取网关IP地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 * 返 回 值：无
 */
void Drv_W5500_GetGAR(W5500_TypeDef *pst_EthStruct, uint8_t *pData)
{
    Drv_W5500_ReadMem(pst_EthStruct, W5500_MR(W5500_GAR0_OFFSET), pData, 4);
}

/**
 * 函数功能：获取子网掩码寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_GetSUBR(W5500_TypeDef *pst_EthStruct, uint8_t *pData)
{
    Drv_W5500_ReadMem(pst_EthStruct, W5500_MR(W5500_SUBR0_OFFSET), pData, 4);
}

/**
 * 函数功能：获取源IP地址寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_GetSIPR(W5500_TypeDef *pst_EthStruct, uint8_t *pData)
{
    Drv_W5500_ReadMem(pst_EthStruct, W5500_MR(W5500_SIPR0_OFFSET), pData, 4);
}

/**
 * 函数功能：获取PHY寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_GetPHY(W5500_TypeDef *pst_EthStruct, uint8_t *pData)
{
    Drv_W5500_ReadReg(pst_EthStruct, W5500_MR(W5500_PHYCFGR_OFFSET), pData);
}

/**
 * 函数功能：设置Sn_MR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_MR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t Data)
{
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_MR(uch_Socket), Data);
}

/**
 * 函数功能：设置Sn_CR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_CR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t Data)
{
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_CR(uch_Socket), Data);
}

/**
 * 函数功能：设置Sn_IR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           pData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_IR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t Data)
{
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_IR(uch_Socket), Data);
}

/**
 * 函数功能：设置Sn_SR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket
 *           uch_Data 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_SR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t uch_Data)
{
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_SR(uch_Socket), uch_Data);
}

/**
 * 函数功能：设置Sn_Port寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket
 *           uin_Data 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_Port(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint16_t uin_Data)
{
    uint8_t auch_Port[2];

    auch_Port[0] = (uin_Data & 0xFF00) >> 8;
    auch_Port[1] = uin_Data & 0x00FF;

    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_PORT0(uch_Socket), auch_Port, 2);
}
/**
 * 函数功能：设置Sn_TX_WR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 *           uin_Data 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_TX_WR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint16_t uin_Data)
{
    uint8_t TxData[2];
    
    TxData[0] = ((uin_Data & 0xFF00) >> 8);
    TxData[1] = uin_Data & 0x00FF;
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_TX_WR0(uch_Socket), TxData, 2);
}

/**
 * 函数功能：设置Sn_RX_RD寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uin_Data 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_Rx_RD(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint16_t uin_Data)
{
    uint8_t TxData[2];
    
    TxData[0] = ((uin_Data & 0xFF00) >> 8);
    TxData[1] = uin_Data & 0x00FF;
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_RX_RD0(uch_Socket), TxData, 2);
}

/**
 * 函数功能：设置Sn_KPALVTR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uin_Data 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_SetSn_KPALVTR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t uch_Data)
{
    Drv_W5500_WriteReg(pst_EthStruct, W5500_Sn_KPALVTR(uch_Socket), uch_Data);
}

/**
 * 函数功能：获取Sn_MR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：Sn_MR寄存器值
 */
uint8_t Drv_W5500_GetSn_MR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_Data;
    
    Drv_W5500_ReadReg(pst_EthStruct, W5500_Sn_MR(uch_Socket), &uch_Data);
    
    return uch_Data;
}

/**
 * 函数功能：获取Sn_CR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint8_t Drv_W5500_GetSn_CR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_Data;
    
    Drv_W5500_ReadReg(pst_EthStruct, W5500_Sn_CR(uch_Socket), &uch_Data);
    
    return uch_Data;
}

/**
 * 函数功能：获取Sn_IR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint8_t Drv_W5500_GetSn_IR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_Data;
    
    Drv_W5500_ReadReg(pst_EthStruct, W5500_Sn_IR(uch_Socket), &uch_Data);
    
    return uch_Data;
}

/**
 * 函数功能：获取Sn_SR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint8_t Drv_W5500_GetSn_SR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_Data;
    
    Drv_W5500_ReadReg(pst_EthStruct, W5500_Sn_SR(uch_Socket), &uch_Data);
    
    return uch_Data;
}

/**
*@brief 	This function is to get socket status
*@param		s: socket number
*@return  socket status
*/
uint8_t Drv_W5500_MyGetSn_SR(uint8_t uch_Socket)
{
	 return getSn_SR((uch_Socket>>2));
   //return IINCHIP_READ(Sn_SR(uch_Socket>>2));
}


/**
 * 函数功能：读取Sn_Port寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint16_t Drv_W5500_GetSn_Port(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;

    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_PORT0(uch_Socket), auch_MemData, 2);
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_TX_FSR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint16_t Drv_W5500_GetSn_TX_FSR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;
    
    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_TX_FSR0(uch_Socket), auch_MemData, 2);
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_Tx_WR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint16_t Drv_W5500_GetSn_TX_WR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;

    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_TX_WR0(uch_Socket), auch_MemData, 2);
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_RX_RSR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint16_t Drv_W5500_GetSn_RX_RSR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;
    
    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_RX_RSR0(uch_Socket), auch_MemData, 2);
    
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_Rx_RD寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 * 返 回 值：无
 */
uint16_t Drv_W5500_GetSn_Rx_RD(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;
    
    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_RX_RD0(uch_Socket), auch_MemData, 2);
    
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_Rx_WR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 * 返 回 值：寄存器值
 */
uint16_t Drv_W5500_GetSn_Rx_WR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t auch_MemData[2];
    uint16_t uin_Data;
    
    Drv_W5500_ReadMem(pst_EthStruct, W5500_Sn_Rx_WR0(uch_Socket), auch_MemData, 2);
    
    uin_Data = (auch_MemData[0] << 8) + auch_MemData[1];
    
    return uin_Data;
}

/**
 * 函数功能：读取Sn_KPALVTR寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           Socket Socket寄存器
 * 返 回 值：Sn_KPALVTR寄存器值
 */
uint8_t Drv_W5500_GettSn_KPALVTR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket)
{
    uint8_t uch_Data;
    
    Drv_W5500_ReadReg(pst_EthStruct, W5500_Sn_KPALVTR(uch_Socket), &uch_Data);
    
    return uch_Data;
}

/**
 * 函数功能：读寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           Addr 寄存器地址
 *           pRxData 数据缓存
 * 返 回 值：无
 */
void Drv_W5500_ReadReg(W5500_TypeDef *pst_EthStruct, uint32_t Addr, uint8_t *pRxData)
{
    uint8_t uch_SendData[4];
    uint8_t uch_ReceiveData[4];

    uch_SendData[0] = (Addr & 0xFF0000) >> 16;
    uch_SendData[1] = (Addr & 0x00FF00) >> 8;
    uch_SendData[2] = (Addr & 0x0000F8);
    uch_SendData[3] = 0x00;

    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_RESET);
    Drv_W5500_Delay(5);
    HAL_SPI_TransmitReceive(pst_EthStruct->pst_hspi, uch_SendData, uch_ReceiveData, 4, 0xffff);
    Drv_W5500_Delay(5);
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_SET);
    
    *pRxData = uch_ReceiveData[3];
}

/**
 * 函数功能：写寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           ul_Addr 寄存器地址
 *           uch_TxData 数据
 * 返 回 值：无
 */
void Drv_W5500_WriteReg(W5500_TypeDef *pst_EthStruct, uint32_t ul_Addr, uint8_t uch_TxData)
{
    uint8_t uch_SendData[4];
    
    uch_SendData[0] = (ul_Addr & 0xFF0000) >> 16;
    uch_SendData[1] = (ul_Addr & 0x00FF00) >> 8;
    uch_SendData[2] = (ul_Addr & 0x0000F8) | W5500_W;
    uch_SendData[3] = uch_TxData;
    
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_RESET);
    Drv_W5500_Delay(5);
    HAL_SPI_Transmit(pst_EthStruct->pst_hspi, uch_SendData, 4, 0xffff);
    Drv_W5500_Delay(5);
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_SET);
}

/**
 * 函数功能：读多个寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           ul_Addr 寄存器地址
 *           puch_RxData 接收数据缓存
 *           uch_Size 接收字节
 */
void Drv_W5500_ReadMem(W5500_TypeDef *pst_EthStruct, uint32_t ul_Addr, uint8_t *puch_RxData, uint16_t uin_Size)
{
    uint8_t uch_SendAddr[3];
    uch_SendAddr[0] = (ul_Addr & 0xFF0000) >> 16;
    uch_SendAddr[1] = (ul_Addr & 0x00FF00) >> 8;
    uch_SendAddr[2] = (ul_Addr & 0x0000F8);
    
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_RESET);
    //Drv_W5500_Delay(5);
    HAL_SPI_Transmit(pst_EthStruct->pst_hspi, uch_SendAddr, 3, 0xffff);
    HAL_SPI_Receive(pst_EthStruct->pst_hspi, puch_RxData, uin_Size, 0xffff);
    //Drv_W5500_Delay(5);
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_SET);
}

/**
 * 函数功能：写多个寄存器
 * 参    数：pst_EthStruct W5500结构体指针
 *           Addr 寄存器地址
 *           puch_TxData 发送数据缓存
 *           uch_Size 发送字节
 */
void Drv_W5500_WriteMem(W5500_TypeDef *pst_EthStruct, uint32_t ul_Addr, uint8_t *puch_TxData, uint16_t uin_Size)
{
    uint8_t uch_SendAddr[3];
    
    uch_SendAddr[0] = (ul_Addr & 0xFF0000) >> 16;
    uch_SendAddr[1] = (ul_Addr & 0x00FF00) >> 8;
    uch_SendAddr[2] = (ul_Addr & 0x0000F8) | W5500_W;
    
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_RESET);
    Drv_W5500_Delay(5);
    HAL_SPI_Transmit(pst_EthStruct->pst_hspi, uch_SendAddr, 3, 0xffff);
    HAL_SPI_Transmit(pst_EthStruct->pst_hspi, puch_TxData, uin_Size, 0xffff);
    Drv_W5500_Delay(5);
    HAL_GPIO_WritePin(pst_EthStruct->pst_CS_GPIO, pst_EthStruct->ul_CS_PIN, GPIO_PIN_SET);
}



/**
 * 函数功能：设置目标服务器IP地址
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 *           puch_ServerIP 目标服务器IP地址（4字节）
 * 返 回 值：无
 */
void Drv_W5500_SetSn_DIPR(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, const uint8_t *puch_ServerIP)
{
    // 写入目标IP地址到对应的Socket寄存器  
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_DIPR0(uch_Socket), puch_ServerIP, 4);
}

/**
 * 函数功能：设置目标服务器端口
 * 参    数：pst_EthStruct W5500结构体指针
 *           uch_Socket Socket寄存器
 *           uin_ServerPort 目标服务器端口号
 * 返 回 值：无
 */
void Drv_W5500_SetSn_DPORT(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint16_t uin_ServerPort)
{
    uint8_t auch_Port[2];

    auch_Port[0] = (uin_ServerPort & 0xFF00) >> 8;
    auch_Port[1] = uin_ServerPort & 0x00FF;

    //Drv_W5500_WriteMem(pst_EthStruct,W5500_MR(W5500_Sn_DPORT0_OFFSET), auch_Port, 2);

     // 写入远程端口寄存器 Sn_DPORT0 和 Sn_DPORT1
    Drv_W5500_WriteMem(pst_EthStruct, W5500_Sn_DPORT0(uch_Socket), auch_Port, 2);
}

/**
 * 函数功能：W5500延时
 * 参    数：uin_Delay 延时计数
 */
static void Drv_W5500_Delay(uint16_t uin_Delay)
{
    for(uint16_t i = 0; i < uin_Delay; i++)
    {
        for (uint16_t j = 0; j < 10; j++);
    }
		//uint32_t target_tick = HAL_GetTick() + uin_Delay;
    //while (HAL_GetTick() < target_tick);
}   


//void check_heartbeat(W5500_TypeDef *pst_EthStruct, uint8_t uch_Socket, uint8_t *puch_ServerIP, uint16_t uin_ServerPort)
//{
//    if (millis() - last_heartbeat_time >= 5000)  // 每5秒发送一次
//    {
//        uint8_t heartbeat[] = {0x00};  // 心跳包内容可以自定义
//        int result = Drv_W5500_TCPSend(pst_EthStruct, uch_Socket, heartbeat, sizeof(heartbeat));
//        
//        if (result <= 0)
//        {
//            printf("Heartbeat failed. Reconnecting...\n");
//				  	Drv_W5500_CloseSocket(pst_EthStruct, uch_Socket);
//            //Drv_W5500_Connect(pst_EthStruct, uch_Socket, puch_ServerIP, uin_ServerPort);
//        }

//        last_heartbeat_time = millis();
//    }
//}





